package org.glutenberg.util.binarytree;

import org.glutenberg.util.Comparator;
import org.glutenberg.util.Comparable;

public class Tree {
	private TreeItem root;
	private int size = 0;

	private boolean allowDuplicates = false;
	private ConflictResolver conflictResolver;
	private Comparator comparator;
	
	public Tree(boolean allowDuplicates){
		this(null, null, allowDuplicates);
	}
	
	public Tree(ConflictResolver conflictResolver, Comparator comparator, boolean allowDuplicates){
		this.allowDuplicates = allowDuplicates;
		this.conflictResolver = conflictResolver;
		this.comparator = comparator;
	}
	
	public void insert(Object key){
		if(this.root == null){
			this.root = new TreeItem(this, key);
			size++;
		}
		else {
			if(this.root.insert(new TreeItem(this, key))){
				size++;
			}
		}
	}
	
	public int size() {
		return size;
	}
	
	public Object searchFirst(Object key){
		if(this.root==null) return null;
		TreeItem item =  (TreeItem)this.root.searchFirst(key);
		if(item!=null) return item.getKey();
		return null;
	}

	public void resolveConflict(TreeItem t1, TreeItem t2){
		if(this.conflictResolver!=null) conflictResolver.resolveConflict(t1.getKey(), t2.getKey());
	}
	
	public int compare(Object o1, Object o2){
		if(this.comparator!=null) return this.comparator.compare(o1, o2);
		else if(o1 instanceof Comparable) return ((Comparable)o1).compareTo(o2);
		return -1;
	}
	
	public boolean getAllowDuplicates() {
		return allowDuplicates;
	}

	public TreeItem getRoot() {
		return root;
	}
}
